package com.fms.kccc;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import com.androidquery.util.AQUtility;
import com.bugsense.trace.BugSenseHandler;
import com.fms.kccc.adapter.ContentViewPagerAdapter;
import com.fms.kccc.adapter.ContentViewPagerAdapter.OnLoadListener;
import com.fms.kccc.cache.Cache;
import com.fms.kccc.cache.Cache.CacheType;
import com.fms.kccc.cache.Cache.OnLoadCacheListener;
import com.fms.kccc.fragment.MenuFragment;
import com.fms.kccc.fragment.MenuFragment.OnSelectMenuListener;
import com.fms.kccc.object.ImageContent;
import com.fms.kccc.service.NetworkReceiver;
import com.fms.kccc.service.NetworkReceiver.OnChangeNetworkStateListener;
import com.fms.kccc.task.GetTask;
import com.fms.kccc.task.GetTask.OnGetTaskListener;
import com.fms.kccc.util.Common;
import com.fms.kccc.util.Common.Variable;
import com.fms.kccc.util.NotificationUtils;
import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu;
import com.jeremyfeinstein.slidingmenu.lib.app.SlidingFragmentActivity;

public class MainActivity extends SlidingFragmentActivity {
	private static final String APIKEY = "f4e67d8d";
	// Layout
	// private PullToRefreshListView lvContent;
	private ViewPager vpContent;
	private ProgressBar pbLoading;
	private ActionBar mActionBar;
	private TextView tvConnectInfo;
	private ImageView ivSplash;

	private SlidingMenu menu;
	// Actionbar
	private ImageButton ibMenu;
	private LinearLayout llReload;
	private TextView tvNumPost;

	// Adapter
	// public ImageListViewAdapter adapter;
	private ContentViewPagerAdapter adapter;

	// Data
	private List<ImageContent> data;

	// Common
	private final int STATE_FIRST_LOAD = 0;
	private final int STATE_LOAD_MORE = 1;
	private final int STATE_REFRESH = 2;
	private int loadState = STATE_FIRST_LOAD;
	private String category = Common.Variable.DEFAULT_CATEGORY;
	private int page = 1;
	private Context context;
	private Cache mainCache;
	private MenuFragment menuFragment;
	private SharedPreferences preferences;

	private boolean isLoadComplete = true;

	public static int appRunningSate = 0;

	private String newPostKey;
	public static int numNewPost = 0;

	private int chap = 0;
	private boolean isMarked = false;
	// private long markedDate;
	private String markedTitle;

	private NetworkReceiver networkReceiver;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		settingActionbar();
		BugSenseHandler.initAndStartSession(this, APIKEY);
		setContentView(R.layout.activity_main);
		context = this;
		settingSlidingMenu();
		findViewIDs();
		init();
		setEvent();
	}

	private void setEvent() {
		vpContent.setOnPageChangeListener(new OnPageChangeListener() {

			@Override
			public void onPageSelected(int position) {
				if (position == 0) {
					adapter.setFirstPage(true);
				} else {
					adapter.setFirstPage(false);
				}

			}

			@Override
			public void onPageScrolled(int arg0, float arg1, int arg2) {

			}

			@Override
			public void onPageScrollStateChanged(int arg0) {

			}
		});
		ibMenu.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				toggle();
			}
		});
		llReload.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				refreshLoad(true);
			}
		});
		adapter.setOnLoadListener(new OnLoadListener() {

			@Override
			public void onLoadMore() {
				loadMore();
			}
		});
	}

	private void init() {
		mainCache = new Cache(context, CacheType.MAIN_CONTENT);
		newPostKey = getResources().getString(R.string.new_post_key);
		preferences = PreferenceManager.getDefaultSharedPreferences(this);
		boolean isNotifySetting = preferences.getBoolean(
				Common.Variable.NOTIFY_SETTING, true);
		if (isNotifySetting) {
			Log.i("kccc", "setupNotification");
			NotificationUtils.setupNotification(context);
		}
		data = new ArrayList<ImageContent>();
		adapter = new ContentViewPagerAdapter(data, context);
		vpContent.setOffscreenPageLimit(2);
		vpContent.setAdapter(adapter);
		adapter.setFirstPage(true);
		setupNetworkInfo();
		isMarked = preferences.getBoolean(Common.Variable.IS_MARKED, false);
		// long current = new Date().getTime();
		// markedDate = preferences.getLong(Common.Variable.MARKED_DATE,
		// current);
		// markedTitle = preferences.getString(Common.Variable.MARKED_TITLE,
		// null);
		if (isMarked) {
			chap = preferences.getInt(Common.Variable.MARKED_CHAP, 0);
			firstMarkedLoad();
		} else {
			chap = 0;
			firstLoad();
		}
	}

	private void setupNetworkInfo() {
		networkReceiver = new NetworkReceiver(context,
				new OnChangeNetworkStateListener() {

					@Override
					public void onChange(boolean isOnline) {
						if (isOnline) {
							tvConnectInfo.setVisibility(View.GONE);
						} else {
							tvConnectInfo.setVisibility(View.VISIBLE);
						}
					}
				});
		this.registerReceiver(networkReceiver, new IntentFilter(
				ConnectivityManager.CONNECTIVITY_ACTION));
	}

	private void findViewIDs() {
		vpContent = (ViewPager) findViewById(R.id.vp_content);
		pbLoading = (ProgressBar) findViewById(R.id.pb_Loading);
		tvConnectInfo = (TextView) findViewById(R.id.tv_connect_info);
		ivSplash = (ImageView) findViewById(R.id.iv_splash);
	}

	private void settingActionbar() {
		mActionBar = getSupportActionBar();
		mActionBar.hide();
		mActionBar.setDisplayHomeAsUpEnabled(false);
		mActionBar.setDisplayShowHomeEnabled(false);
		mActionBar.setDisplayShowCustomEnabled(true);
		mActionBar.setDisplayShowTitleEnabled(false);
		mActionBar.setCustomView(getActionbarView());

	}

	private View getActionbarView() {
		View view = getLayoutInflater().inflate(R.layout.actionbar_main, null);
		ibMenu = (ImageButton) view.findViewById(R.id.ib_menu);
		llReload = (LinearLayout) view.findViewById(R.id.ll_reload);
		tvNumPost = (TextView) view.findViewById(R.id.tv_num_post);
		return view;
	}

	private void settingSlidingMenu() {
		setBehindContentView(R.layout.menu_frame);
		FragmentTransaction t = this.getSupportFragmentManager()
				.beginTransaction();
		menuFragment = MenuFragment.newInstance();
		menuFragment.setOnSelectMenuListener(new OnSelectMenuListener() {

			@Override
			public void onExit() {
				// finish();
				toggle();
				if (data.size() > 0) {
					showSaveConfirm();
				} else {
					showExitConfirm();
				}

			}

			@Override
			public void onSelectCategory(String category) {
				toggle();
			}

			@Override
			public void onSelectAction(boolean isGotoNew) {
				refreshLoad(isGotoNew);
				toggle();
			}

			@Override
			public void onGotoChap(int mChap) {
				chap = mChap;
				refreshLoad(false);
				toggle();
			}
		});
		t.replace(R.id.menu_frame, menuFragment);
		t.commit();
		menu = getSlidingMenu();
		menu.setMode(SlidingMenu.LEFT);
		menu.setTouchModeAbove(SlidingMenu.TOUCHMODE_MARGIN);
		menu.setBehindOffset(100);
	}

	public void notifyNewPost() {
		// numNewPost = numNewPost + 1;
		mActionBar.show();
		tvNumPost.setVisibility(View.VISIBLE);
		tvNumPost.setText(numNewPost + " " + newPostKey);
	}

	private BroadcastReceiver notifyNewPostReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			String message = intent.getStringExtra(Common.Variable.MESSAGE);
			Log.d("receiver", "Got message: " + message);
			notifyNewPost();
		}
	};

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getSupportMenuInflater().inflate(R.menu.main, menu);
		return false;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case android.R.id.home:
			toggle();
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	@Override
	protected void onResume() {
		// Log.d("kccc", "onResume()");
		super.onResume();
		if (numNewPost > 0) {
			notifyNewPost();
		}
		appRunningSate = 2;
		LocalBroadcastManager.getInstance(this).registerReceiver(
				notifyNewPostReceiver,
				new IntentFilter(Common.Intent.NOTIFY_NEW_POST));
	}

	@Override
	protected void onPause() {
		appRunningSate = 1;
		LocalBroadcastManager.getInstance(this).unregisterReceiver(
				notifyNewPostReceiver);
		super.onPause();
	}

	@Override
	protected void onStop() {
		super.onStop();
	}

	@Override
	protected void onDestroy() {
		appRunningSate = 0;
		if (isTaskRoot()) {
			// clean the file cache with advance option
			long triggerSize = 10000000; // starts cleaning when cache size is
											// larger than 3M
			long targetSize = 5000000; // remove the least recently used files
										// until cache size is less than 2M
			AQUtility.cleanCacheAsync(this, triggerSize, targetSize);
		}
		if (networkReceiver != null) {
			this.unregisterReceiver(networkReceiver);
		}
		super.onDestroy();
	}

	@Override
	public void onBackPressed() {
		if (data.size() > 0) {
			showSaveConfirm();
		} else {
			showExitConfirm();
		}
	}

	public void firstLoad() {
		page = 1;
		loadState = STATE_FIRST_LOAD;
		isMarked = false;
		chap = 0;
		getDataFromServer(getDataURL());
	}

	public void firstMarkedLoad() {
		page = 1;
		isMarked = true;
		loadState = STATE_FIRST_LOAD;
		getDataFromServer(getDataURL());
	}

	public void loadMore() {
		page++;
		loadState = STATE_LOAD_MORE;
		getDataFromServer(getDataURL());
	}

	public void refreshLoad(boolean isGotoNew) {
		page = 1;
		if (isGotoNew) {
			isMarked = false;
			chap = 0;
		} else {
			isMarked = true;
		}

		loadState = STATE_REFRESH;
		getDataFromServer(getDataURL());
	}

	public void showLoading() {
		pbLoading.setVisibility(View.VISIBLE);
		vpContent.setVisibility(View.GONE);
		// lvContent.getRefreshableView().setVisibility(View.GONE);
	}

	public void hideLoading() {
		pbLoading.setVisibility(View.GONE);
		vpContent.setVisibility(View.VISIBLE);
		// lvContent.getRefreshableView().setVisibility(View.VISIBLE);
	}

	public void showSFlash() {
		mActionBar.hide();
		ivSplash.setVisibility(View.VISIBLE);
		Animation animation = AnimationUtils.loadAnimation(this, R.anim.fade);
		animation.setDuration(3000);
		ivSplash.startAnimation(animation);
	}

	public void hideSFLash() {
		ivSplash.setVisibility(View.GONE);
		mActionBar.show();
		ivSplash.setAnimation(null);
		vpContent.setVisibility(View.VISIBLE);
	}

	public String getDataURL() {
		// Page begin at 1 not at 0
		if (page == 0)
			page = 1;
		return String.format(Common.RequestURL.GET_IMAGE_CONTENTS, chap,
				category, page);
	}

	public void getDataFromServer(String url) {
		if (isLoadComplete) {
			isLoadComplete = false;
			GetTask loadData = new GetTask(url);
			loadData.setOnGetTaskListener(new OnGetTaskListener() {

				@Override
				public void onSuccess(String result) {
					Log.d("kccc", result);
					doOnSuccess(result);
					isLoadComplete = true;
				}

				@Override
				public void onPreExecute() {
					doOnPreExcute();
				}

				@Override
				public void onFail() {
					doOnFail();
					isLoadComplete = true;
				}
			});
			loadData.execute();
		}

	}

	protected void doOnSuccess(String result) {
		switch (loadState) {
		case STATE_FIRST_LOAD:
			if (!isMarked) {
				tvNumPost.setVisibility(View.GONE);
				numNewPost = 0;
			}
			mainCache.writeCache(result);
			data.clear();
			data.addAll(ImageContent.fromJsonArrayToImageContents(result));
			adapter.notifyDataSetChanged();
			vpContent.setCurrentItem(0);
			break;
		case STATE_LOAD_MORE:
			data.addAll(ImageContent.fromJsonArrayToImageContents(result));
			adapter.notifyDataSetChanged();
			break;
		case STATE_REFRESH:
			if (!isMarked) {
				tvNumPost.setVisibility(View.GONE);
				numNewPost = 0;
			}
			mainCache.writeCache(result);
			data.clear();
			data.addAll(ImageContent.fromJsonArrayToImageContents(result));
			adapter.notifyDataSetChanged();
			vpContent.setCurrentItem(0);
			break;
		default:
			break;
		}
		doOnPostExecute();
	}

	private void doOnPostExecute() {
		switch (loadState) {
		case STATE_FIRST_LOAD:
			// hideLoading();
			hideSFLash();
			break;
		case STATE_LOAD_MORE:
			// lvContent.getRefreshableView().removeFooterView(footerView);
			break;
		case STATE_REFRESH:
			// lvContent.onRefreshComplete();
			hideLoading();
			break;
		default:
			break;
		}
	}

	protected void doOnFail() {
		Log.d("kccc", "LoadImageContentsFromServer Fail, load from Cache!");
		mainCache.setOnLoadCacheListener(new OnLoadCacheListener() {

			@Override
			public void onFail() {
				Log.d("kccc", "load from Cache fail");
			}

			@Override
			public void onComplete(String result) {
				switch (loadState) {
				case STATE_FIRST_LOAD:
					data.clear();
					data.addAll(ImageContent
							.fromJsonArrayToImageContents(result));
					adapter.notifyDataSetChanged();
					break;
				case STATE_LOAD_MORE:
					break;
				case STATE_REFRESH:
					data.clear();
					data.addAll(ImageContent
							.fromJsonArrayToImageContents(result));
					adapter.notifyDataSetChanged();
					break;
				default:
					break;
				}
			}
		});
		doOnPostExecute();
	}

	protected void doOnPreExcute() {
		switch (loadState) {
		case STATE_FIRST_LOAD:
			// showLoading();
			showSFlash();
			break;
		case STATE_LOAD_MORE:
			getLayoutInflater().inflate(R.layout.lv_item_footer, null);
			// lvContent.getRefreshableView().addFooterView(footerView);
			break;
		case STATE_REFRESH:
			showLoading();
			break;
		default:
			break;
		}
	}

	private void showSaveConfirm() {
		AlertDialog.Builder builder = new Builder(this);
		builder.setMessage(getResources().getString(R.string.save_title));
		builder.setPositiveButton("Quay lại",
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						dialog.cancel();
					}
				});

		builder.setNegativeButton("Có", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				preferences.edit().putBoolean(Variable.IS_MARKED, true)
						.commit();
				ImageContent imageContent = data.get(vpContent.getCurrentItem());
				preferences.edit()
						.putInt(Variable.MARKED_CHAP, imageContent.getChap())
						.commit();
				preferences
						.edit()
						.putString(Variable.MARKED_TITLE,
								imageContent.getTitle()).commit();
				finish();
			}
		});

		builder.setNeutralButton("Không",
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						preferences.edit()
								.putBoolean(Variable.IS_MARKED, false).commit();
						ImageContent imageContent = data.get(vpContent
								.getCurrentItem());
						preferences
								.edit()
								.putInt(Variable.MARKED_CHAP,
										imageContent.getChap()).commit();
						preferences
								.edit()
								.putString(Variable.MARKED_TITLE,
										imageContent.getTitle()).commit();
						finish();
					}
				});

		builder.create().show();
	}

	private void showExitConfirm() {
		AlertDialog.Builder builder = new Builder(this);
		builder.setMessage(getResources().getString(R.string.exit_title));

		builder.setNegativeButton("Có", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				finish();
			}
		});

		builder.setNeutralButton("Không",
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						dialog.cancel();
					}
				});

		builder.create().show();
	}
}
